package models;

import java.util.ArrayList;
import java.util.List;

import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.criterion.Restrictions;

public class HibernateDBGestion {
	private Session currentSession = null ;

	public HibernateDBGestion() {}
	
	/**
	 * Start a connection to the database
	 */
	public void startConnection() {
		this.currentSession = HibernateTools.getSessionFactory().openSession() ;
	}
	
	/**
	 * @return the current session
	 */
	protected Session getSession() {
		return this.currentSession ;
	}

	/**
	 * End the current connection to the database
	 */
	public void endConnection() {
		if (this.currentSession != null) {
			this.currentSession.close() ;
		}
		this.currentSession = null ;
	}
	
	/**
	 * @param doc - the document that we want to save or update
	 */
	public void saveOrUpdateDoc(HibernateDocument doc){
		Session session = this.currentSession;
		Transaction tx = session.beginTransaction();
		session.saveOrUpdate(doc);
		tx.commit();
	}
	
	/**
	 * @param wordList - list the word that we want to save or update
	 */
	public void saveOrUpdateWordList(ArrayList<HibernateWord> wordList){
		Session session = this.currentSession;
		Transaction tx = session.beginTransaction();
		for(HibernateWord word : wordList){
			session.saveOrUpdate(word);
		}
		tx.commit();
	}

	/**
	 * @param tagList - list the tag that we want to save or update
	 */
	public void saveOrUpdateTagList(ArrayList<HibernateTags> tagList){
		Session session = this.currentSession;
		Transaction tx = session.beginTransaction();
		for(HibernateTags tag : tagList){
			session.saveOrUpdate(tag);
		}
		tx.commit();
	}
	
	/**
	 * @param occList - list the occurrence that we want to save or update
	 */
	public void saveOrUpdateOccList(ArrayList<HibernateOccurence> occList){
		Session session = this.currentSession;
		Transaction tx = session.beginTransaction();
		for(HibernateOccurence occ : occList){
			session.saveOrUpdate(occ);
		}
		tx.commit();
	}
	
	/**
	 * @param posList - list the position that we want to save or update
	 */
	public void saveOrUpdatePosList(ArrayList<HibernatePosition> posList){
		Session session = this.currentSession;
		Transaction tx = session.beginTransaction();
		for(HibernatePosition pos : posList){
			session.saveOrUpdate(pos);
		}
		tx.commit();
	}
	
	/**
	 * @param ch - the word that we want to find
	 * @return the word object if it exists unique in the database
	 * @throws HibernateException
	 */
	public HibernateWord getWordByString(String ch) throws HibernateException{
		HibernateWord w = (HibernateWord)this.currentSession.createCriteria(HibernateWord.class)
				.add(Restrictions.eq("mot", ch))
				.uniqueResult() ;
		return w;

	}
	
	/**
	 * @param ch - the word that we want to find
	 * @return the list of word object if there are more than one result for it
	 */
	public List getListByString(String ch){
		List l = this.currentSession.createCriteria(HibernateWord.class)
				.add(Restrictions.eq("mot", ch))
				.list() ;
		return l;
	}
	
	/**
	 * @return all the tag whose size is greater than 0
	 */
	public List getListSizePositifTag(){
		return this.currentSession.createCriteria(HibernateTags.class)
				.add(Restrictions.gt("taille", 0))
				.list();
	}
	
	/**
	 * @param tagId - the tag in which we want to get the occurrences
	 * @return all the occurrence of this tag
	 */
	public List getListOccByContainer(HibernateTags tagId){
		return this.currentSession.createCriteria(HibernateOccurence.class)
				.add(Restrictions.eq("paraId", tagId))
				.list();
	}
	
	/**
	 * @param wordId - the targeted word
	 * @return all the occurrence of this word
	 */
	public List getListOccByElement(HibernateWord wordId){
		return this.currentSession.createCriteria(HibernateOccurence.class)
				.add(Restrictions.eq("motId", wordId))
				.list();
	}
	
	/**
	 * @return all the word of the database
	 */
	public List getAllWord(){
		return this.currentSession.createCriteria(HibernateWord.class)
				.list();
	}
	
	/**
	 * @param sec - the targeted <Section>
	 * @return all the P tag under this targeted section
	 */
	public List getListPOfSec(HibernateTags sec){
		return this.currentSession.createCriteria(HibernateTags.class)
				.add(Restrictions.eq("tagFather", sec))
				.add(Restrictions.eq("typeB", "P"))
				.list();
	}
	
	/**
	 * @param ps - the targeted <Presentation>
	 * @return all the P tag under this targeted Presentation
	 */
	public List getListPOfPresentation(HibernateTags ps){
		return this.currentSession.createCriteria(HibernateTags.class)
				.add(Restrictions.eq("docID", ps.getDocID()))
				.add(Restrictions.eq("typeB", "P"))
				.list();
	}
}
